package com.hmdp.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.hmdp.dto.Result;
import com.hmdp.utils.SystemConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Slf4j
@RestController
@RequestMapping("upload")
public class UploadController {

    @PostMapping("blog")
    public Result uploadImage(@RequestParam("file") MultipartFile image) {
        try {
            // 获取原始文件名称
            String originalFilename = image.getOriginalFilename();
            // 生成新文件名
            String fileName = createNewFileName(originalFilename);
            // 保存文件
            image.transferTo(new File(SystemConstants.IMAGE_UPLOAD_DIR, fileName));
            // 返回结果
            log.debug("文件上传成功，{}", fileName);
            return Result.ok(fileName);
        } catch (IOException e) {
            throw new RuntimeException("文件上传失败", e);
        }
    }

    @GetMapping("/blog/delete")
    public Result deleteBlogImg(@RequestParam("name") String filename) {
        File file = new File(SystemConstants.IMAGE_UPLOAD_DIR, filename);
        if (file.isDirectory()) {
            return Result.fail("错误的文件名称");
        }
        FileUtil.del(file);
        return Result.ok();
    }

    private String createNewFileName(String originalFilename) {
        // 获取后缀
//        StrUtil.subAfter 是 Hutool 工具库中字符串处理类 StrUtil 提供的一个方法，用于获取指定字符串中某个分隔符之后的子串。
        String suffix = StrUtil.subAfter(originalFilename, ".", true);
        // 生成目录
        String name = UUID.randomUUID().toString();//首先通过UUID.randomUUID().toString()生成一个随机的 UUID 字符串，作为文件名的基础
        int hash = name.hashCode();//计算该 UUID 字符串的哈希码hash
        //通过位运算从哈希码中提取两个 16 进制的数字：
        int d1 = hash & 0xF;//d1 = hash & 0xF：获取哈希值的最后 4 位，范围是 0-15
        int d2 = (hash >> 4) & 0xF;//d2 = (hash >> 4) & 0xF：获取哈希值的第 5-8 位，范围也是 0-15
        // 判断目录是否存在
        File dir = new File(SystemConstants.IMAGE_UPLOAD_DIR, StrUtil.format("/blogs/{}/{}", d1, d2));//然后以SystemConstants.IMAGE_UPLOAD_DIR为基础目录,构建目录路径：
        //加上/blogs/{d1}/{d2}的子目录结构，其中d1和d2是前面计算得到的两个值
//最后检查目录是否存在，如果不存在则创建该目录（包括所有不存在的父目录）
        if (!dir.exists()) {
            dir.mkdirs();
        }
        // 生成文件名
        return StrUtil.format("/blogs/{}/{}/{}.{}", d1, d2, name, suffix);
    }
}
